﻿using AutoMapper;
using Microsoft.EntityFrameworkCore;
using QMERP.Domain.Dtos;
using QMERP.Domain.Entities;
using QMERP.Domain.Enums;
using QMERP.Domain.PrintModels;
using QMERP.Infrastructure.CustomException;
using QMERP.Infrastructure.EFCore;
using QMERP.Infrastructure.EFCore.Extensions;
using QMERP.Infrastructure.Extensions;
using QMERP.Infrastructure.Security;
using System.Data;

namespace QMERP.Application.Services
{
    public class LeaveStockOrderService : ILeaveStockOrderService
    {
        private readonly IMapper _mapper;
        private readonly QMERPDbContext _db;
        private readonly ICurrentUser _currentUser;
        private readonly ISerialNumberService _serialNumberSvc;
        public LeaveStockOrderService(IMapper mapper, QMERPDbContext db, ICurrentUser currentUser, ISerialNumberService serialNumberSvc)
        {
            _mapper = mapper;
            _db = db;
            _currentUser = currentUser;
            _serialNumberSvc = serialNumberSvc;
        }
        /// <summary>
        /// 出库单窗体
        /// </summary>
        /// <returns></returns>
        public async Task<PageResponse<LeaveStockOrderResponse>> Query(PageRequest<LeaveStockOrderRequest> request)
        {
            var response = new PageResponse<LeaveStockOrderResponse>();
            var query = Where(request);
            var list = await query.Paging(request.PageIndex, request.PageSize).ToListAsync();
            response.TotalCount = await query.CountAsync();
            response.PageIndex = request.PageIndex;
            response.PageSize = request.PageSize;
            response.List = _mapper.Map<List<LeaveStockOrderResponse>>(list);
            return response;
        }
        /// <summary>
        /// 获取id的出库单详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<LeaveStockOrderResponse> Detail(long id)
        {
            var model = await _db.LeaveStockOrder
                .Include(x => x.LeaveStockOrderDetails).ThenInclude(x => x.LeaveStockOrderDetail_LensDetails)
                .Include(x => x.LeaveStockOrderDetails).ThenInclude(x => x.Warehouse)
                .Include(x => x.LeaveStockOrderDetails).ThenInclude(x => x.Lens).AsNoTracking().FindByIdAsync(id);
            var response = _mapper.Map<LeaveStockOrderResponse>(model);
            return response;
        }
        /// <summary>
        /// 获取对应业务单类型可出库的订单列表
        /// </summary>
        /// <param name="businessOrderType"></param>
        /// <returns></returns>
        public async Task<List<CanLeaveStockOrderResponse>> GetCanLeaveStockOrders(string businessOrderType)
        {
            List<CanLeaveStockOrderResponse> canLeaveStockOrders = new();
            if (businessOrderType == LeaveStockBusinessOrderTypeEnum.RetailOrder.ToString())
            {
                var orders = await _db.RetailOrder
                    .Include(x => x.RetailOrderDetails).ThenInclude(x => x.Warehouse)
                    .Include(x => x.RetailOrderDetails).ThenInclude(x => x.Contract_Lens).ThenInclude(x => x!.Lens).Where(x => x.Status == RetailOrderStatusEnum.Delivery.ToString()).ToListAsync();
                foreach (var order in orders)
                {
                    CanLeaveStockOrderResponse canLeaveStockOrder = new()
                    {
                        BusinessOrderId = order.Id,
                        BusinessOrderNumber = order.Number
                    };
                    var lenses = order.RetailOrderDetails.Select(s => new { s.WarehouseId, s.Contract_LensId }).Distinct().ToList();
                    foreach (var lens in lenses)
                    {
                        var retailOrderDetails = order.RetailOrderDetails.Where(x => x.WarehouseId == lens.WarehouseId && x.Contract_LensId == lens.Contract_LensId).ToList();

                        if (retailOrderDetails != null && retailOrderDetails.Count > 0)
                        {
                            var ranges = order.RetailOrderDetails.Where(x => x.WarehouseId == lens.WarehouseId && x.Contract_LensId == lens.Contract_LensId).Select(s => new { s.SPH, s.CYL }).Distinct().ToList();
                            foreach (var range in ranges)
                            {
                                var details = retailOrderDetails.Where(x => x.SPH == range.SPH && x.CYL == range.CYL ).ToList();
                                List<LensDetailResponse> lensDetails = new()
                                {
                                    new LensDetailResponse() 
                                    {
                                        DegreesType = details[0].DegreesType,
                                        SPH = details[0].SPH,
                                        CYL = details[0].CYL,
                                        ADD = details[0].ADD,
                                        Qty = details.Sum(s => s.Qty),
                                    }
                                };
                                LeaveStockOrderDetailResponse leaveStockOrderDetail = new()
                                {
                                    Warehouse = _mapper.Map<WarehouseResponse>(details[0].Warehouse),
                                    Lens = _mapper.Map<LensResponse>(details[0].Contract_Lens!.Lens),
                                    Qty = details.Sum(s => s.Qty),
                                    WarehouseId = details[0].Warehouse!.Id,
                                    LensId = details[0].Contract_Lens!.LensId,
                                    LensDetails = lensDetails
                                };
                                canLeaveStockOrder.LeaveStockOrderDetails.Add(leaveStockOrderDetail);
                            }

                        }
                    }
                    canLeaveStockOrders.Add(canLeaveStockOrder);
                }
                return canLeaveStockOrders;
            }
            else if (businessOrderType == LeaveStockBusinessOrderTypeEnum.BulkOrder.ToString())
            {
                var list = await _db.BulkOrder
                    .Include(x => x.BulkOrderDetails).ThenInclude(x => x.Warehouse)
                    .Include(x => x.BulkOrderDetails).ThenInclude(x => x.Contract_Lens).ThenInclude(x => x!.Lens)
                    .Include(x => x.BulkOrderDetails).ThenInclude(x => x.BulkOrderDetail_LensDetails).Where(x => x.Type == BulkOrderTypeEnum.Product.ToString() && x.Status == BulkOrderStatusEnum.Delivery.ToString() || x.Status == BulkOrderStatusEnum.PartialDelivered.ToString()).ToListAsync();
                canLeaveStockOrders = _mapper.Map<List<CanLeaveStockOrderResponse>>(list);
            }
            else if(businessOrderType == LeaveStockBusinessOrderTypeEnum.TransferOrder.ToString())
            {
                var list = await _db.TransferOrder
                    .Include(x => x.TransferOrderDetails).ThenInclude(x => x.OutWarehouse)
                    .Include(x => x.TransferOrderDetails).ThenInclude(x => x.InWarehouse)
                    .Include(x => x.TransferOrderDetails).ThenInclude(x => x.Lens)
                    .Include(x => x.TransferOrderDetails).ThenInclude(x => x.TransferOrderDetail_LensDetails).Where(x => x.Status == TransferOrderStatusEnum.Receive.ToString() || x.Status == TransferOrderStatusEnum.PartialReceived.ToString()).ToListAsync();
                canLeaveStockOrders = _mapper.Map<List<CanLeaveStockOrderResponse>>(list);
            }
            else if(businessOrderType == LeaveStockBusinessOrderTypeEnum.TransferLensOrder.ToString())
            {
                var list = await _db.TransferLensOrder
                    .Include(x => x.TransferLensOrderDetails).ThenInclude(x => x.OutWarehouse)
                    .Include(x => x.TransferLensOrderDetails).ThenInclude(x => x.OutLens)
                    .Include(x => x.TransferLensOrderDetails).ThenInclude(x => x.InWarehouse)
                    .Include(x => x.TransferLensOrderDetails).ThenInclude(x => x.InLens)
                    .Include(x => x.TransferLensOrderDetails).ThenInclude(x => x.TransferLensOrderDetail_LensDetails).Where(x => x.Status == TransferLensOrderStatusEnum.Checked.ToString()).ToListAsync();
                canLeaveStockOrders = _mapper.Map<List<CanLeaveStockOrderResponse>>(list);
            }

            for (int i = canLeaveStockOrders.Count - 1; i >= 0; i--)
            {
                var canLeaveStockOrder = canLeaveStockOrders[i];
                var orders = await _db.LeaveStockOrder.GetByBusinessOrderIdAsync(businessOrderType, canLeaveStockOrder.BusinessOrderId).ToListAsync();
                var qty = canLeaveStockOrder.LeaveStockOrderDetails.SelectMany(s => s.LensDetails).Sum(s => s.Qty);
                var orderQty = orders.SelectMany(s => s.LeaveStockOrderDetails).SelectMany(s => s.LeaveStockOrderDetail_LensDetails).Sum(s => s.Qty);
                if (qty == orderQty)
                {
                    canLeaveStockOrders.Remove(canLeaveStockOrder);
                }
                else
                {
                    foreach (var detail in canLeaveStockOrder.LeaveStockOrderDetails)
                    {
                        foreach (var lensDetail in detail.LensDetails)
                        {
                            int leaveStockQty = orders.SelectMany(s => s.LeaveStockOrderDetails).SelectMany(s => s.LeaveStockOrderDetail_LensDetails).Where(x => x.DegreesType == lensDetail.DegreesType && x.SPH == lensDetail.SPH && x.CYL == lensDetail.CYL).Sum(s => s.Qty);
                            lensDetail.Qty = lensDetail.Qty - leaveStockQty;
                        }
                    }
                }
            }
            return canLeaveStockOrders;
        }
        /// <summary>
        /// 出库单保存
        /// </summary>
        /// <param name="request"></param>
        /// <param name="isCheck"></param>
        /// <returns></returns>
        /// <exception cref="ApiException"></exception>
        public async Task<LeaveStockOrderResponse> Save(LeaveStockOrderSaveRequest request, bool isCheck = false)
        {
            if (request.LeaveStockOrderDetails.Count <= 0)
                throw new ApiException($"{request.BusinessOrderNumber}请添加出库镜种信息!");

            var leaveStockQty = request.LeaveStockOrderDetails.SelectMany(s => s.LensDetails).Sum(s => s.Qty);

            if (leaveStockQty <= 0)
                throw new ApiException($"{request.BusinessOrderNumber}出库总片数不能小于等于0");

            for (int i = 0; i < request.LeaveStockOrderDetails.Count; i++)
            {
                string col = $"第{i + 1}行:";
                var detail = request.LeaveStockOrderDetails[i];
                var stock = await _db.Stock.GetByWarehouseLens(detail.WarehouseId, detail.LensId);
                if (request.BusinessOrderId == null)
                {
                    if (detail.LensDetails.Count <= 0)
                        throw new ApiException($"{col}请导入XY表!");

                    if (detail.LensDetails.Sum(s => s.Qty) <= 0)
                        throw new ApiException($"{col}XY表总片数为0,请检查!");
                }
                if (!detail.LensDetails.InRange(_mapper.Map<LensResponse>(stock.Lens)))
                    throw new ApiException($"{col}XY表度数超出镜种范围!");

                detail.LensDetails = detail.LensDetails.Where(x => x.Qty > 0).ToList();

                foreach (var lensDetail in detail.LensDetails)
                {
                    var stockDetail = stock.GetByRange(lensDetail.DegreesType, lensDetail.SPH, lensDetail.CYL);
                    if (stockDetail.Qty - lensDetail.Qty < 0)
                    {
                        throw new ApiException($"{col}仓库{stock.Warehouse?.Code}镜种{stock.Lens?.SalesLensCode}度数SPH:{lensDetail.SPH},CYL{lensDetail.CYL}库存片数不足扣库");
                    }
                }
            }

            LeaveStockOrder? model = _mapper.Map<LeaveStockOrder>(request);
            if (request.Id != null)
            {
                model = await _db.LeaveStockOrder.Include(x => x.LeaveStockOrderDetails).ThenInclude(x => x.LeaveStockOrderDetail_LensDetails).FindByIdAsync(request.Id.Value);
                if (model == null)
                    throw new ApiException("出库单不存在!");
                model.Remark = request.Remark;
                model.BusinessType = request.BusinessType;
                model.LeaveStockOrderDetails = _mapper.Map<List<LeaveStockOrderDetail>>(request.LeaveStockOrderDetails);
            }
            await ModifyBusinessOrder(model);
            if (request.Id == null)
            {
                string mumber = await _serialNumberSvc.GetSerialNumber(SerialNumberTypeEnum.LeaveStockOrder);
                model.Number = mumber;
                model.Status = LeaveStockOrderStatusEnum.Pending.ToString();
                await _db.AddAsync(model);
            }
            await _db.SaveChangesAsync();
            if (isCheck)
            {
                model = await _db.LeaveStockOrder
                .Include(x => x.LeaveStockOrderDetails).ThenInclude(x => x.LeaveStockOrderDetail_LensDetails)
                .Include(x => x.LeaveStockOrderDetails).ThenInclude(x => x.Warehouse)
                .Include(x => x.LeaveStockOrderDetails).ThenInclude(x => x.Lens).FindByIdAsync(model.Id);
                if (model != null)
                {
                    await Check(model);
                    await _db.SaveChangesAsync();
                }
            }
            return _mapper.Map<LeaveStockOrderResponse>(model);
        }
        /// <summary>
        /// 出库单审核
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public async Task Check(long[] ids)
        {
            if (ids == null)
                throw new ApiException("id不能为空!");
            var orders = await _db.LeaveStockOrder
                .Include(x => x.LeaveStockOrderDetails).ThenInclude(x => x.LeaveStockOrderDetail_LensDetails)
                .Include(x => x.LeaveStockOrderDetails).ThenInclude(x => x.Warehouse)
                .Include(x => x.LeaveStockOrderDetails).ThenInclude(x => x.Lens).Where(x => ids.Contains(x.Id)).ToListAsync();
            foreach (var order in orders)
            {
                if (order.Status != LeaveStockOrderStatusEnum.Pending.ToString())
                    throw new ApiException($"出库单号{order.Number}不能审核!");
                await Check(order);
            }
            await _db.SaveChangesAsync();
        }
        /// <summary>
        /// 出库单弃审
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public async Task UnCheck(long[] ids)
        {
            if (ids == null)
                throw new ApiException("id不能为空!");
            var orders = await _db.LeaveStockOrder
                .Include(x => x.LeaveStockOrderDetails).ThenInclude(x => x.LeaveStockOrderDetail_LensDetails).Include(x => x.EnterStockOrders).Where(x => ids.Contains(x.Id)).ToListAsync();
            foreach (var order in orders)
            {
                if (order.Status != LeaveStockOrderStatusEnum.Checked.ToString())
                    throw new ApiException($"出库单号{order.Number}不能弃审!");
                //弃审时对应未审核入库单列表设置取消状态
                foreach (var enterStockOrder in order.EnterStockOrders)
                {
                    if (enterStockOrder.Status == EnterStockOrderStatusEnum.Checked.ToString())
                        throw new ApiException($"出库单号{order.Number}对应入库单号{enterStockOrder.Number}已审核,不能弃审!");
                    if (enterStockOrder.Status == EnterStockOrderStatusEnum.Pending.ToString())
                        enterStockOrder.Status = EnterStockOrderStatusEnum.Canceled.ToString();
                }
                await UnCheckOrCancel(order);
                order.Status = LeaveStockOrderStatusEnum.Pending.ToString();
                order.CheckedBy = null;
                order.CheckedByName = null;
                order.CheckedOn = null;
            }
            await _db.SaveChangesAsync();
        }
        /// <summary>
        /// 出库单取消
        /// </summary>
        /// <param name="ids"></param>
        /// <param name="isOther"></param>
        /// <returns></returns>
        /// <exception cref="ApiException"></exception>
        public async Task Cancel(long[] ids, bool isOther = false)
        {
            if (ids == null)
                throw new ApiException("id不能为空!");
            var orders = await _db.LeaveStockOrder
                .Include(x => x.LeaveStockOrderDetails).ThenInclude(x => x.LeaveStockOrderDetail_LensDetails).Include(x => x.EnterStockOrders).Where(x => ids.Contains(x.Id)).ToListAsync();
            foreach (var order in orders)
            {
                if (!isOther)
                {
                    if (order.BusinessOrderType == LeaveStockBusinessOrderTypeEnum.InventoryOrder.ToString())
                        throw new ApiException($"库存盘点单号{order.BusinessOrderNumber}对应的出库单号{order.Number}不能取消!");
                }
                if (order.Status != LeaveStockOrderStatusEnum.Pending.ToString() && order.Status != LeaveStockOrderStatusEnum.Checked.ToString())
                    throw new ApiException($"出库单号{order.Number}不能取消!");
                //取消时对应未审核入库单列表设置取消状态
                foreach (var enterStockOrder in order.EnterStockOrders)
                {
                    if (enterStockOrder.Status == EnterStockOrderStatusEnum.Checked.ToString())
                        throw new ApiException($"出库单号{order.Number}对应入库单号{enterStockOrder.Number}已审核,不能取消!");
                    if (enterStockOrder.Status == EnterStockOrderStatusEnum.Pending.ToString())
                        enterStockOrder.Status = EnterStockOrderStatusEnum.Canceled.ToString();
                }
                await UnCheckOrCancel(order);
                order.Status = LeaveStockOrderStatusEnum.Canceled.ToString();
            }
            await _db.SaveChangesAsync();
        }
        /// <summary>
        /// 获取出库单主要信息列表
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<List<LeaveStockOrderMainInfoResponse>> GetLeaveStockOrderMainInfos(PageRequest<LeaveStockOrderRequest> request)
        {
            var orders = await Where(request).ToListAsync();
            var details = orders.SelectMany(s => s.LeaveStockOrderDetails).ToList();
            return _mapper.Map<List<LeaveStockOrderMainInfoResponse>>(details);
        }
        /// <summary>
        /// 获取出库单打印数据
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public async Task<LeaveStockBill> GetLeaveStockBill(long[] ids)
        {
            var orders = await _db.LeaveStockOrder
                .Include(x => x.LeaveStockOrderDetails).ThenInclude(x => x.LeaveStockOrderDetail_LensDetails)
                .Include(x => x.LeaveStockOrderDetails).ThenInclude(x => x.Warehouse)
                .Include(x => x.LeaveStockOrderDetails).ThenInclude(x => x.Lens).AsNoTracking().Where(x=> ids.Contains(x.Id)).ToListAsync();
            //var response = _mapper.Map<RetailOrderResponse>(model);
            if (orders.Count<=0)
            {
                throw new ApiException("出库单不存在!");
            }
            LeaveStockBill leaveStockBill = new();
            foreach (var order in orders)
            {
                if (order.BusinessOrderType == LeaveStockBusinessOrderTypeEnum.RetailOrder.ToString())
                {
                    var retailOrder = await _db.RetailOrder.Include(x => x.Contract).Include(x => x.Customer)
                    .Include(x => x.RetailOrderDetails).ThenInclude(x => x.Contract_Lens).ThenInclude(x => x!.Lens)
                    .Include(x => x.RetailOrderDetails).ThenInclude(x => x.Warehouse).AsNoTracking().FindByIdAsync(order.BusinessOrderId!.Value);
                    var retailOrderDetails = retailOrder!.RetailOrderDetails.ToList();
                    var detailR = retailOrderDetails[0];
                    var detailL = retailOrderDetails[1];
                    RetailOrderLeaveStockBill retailOrderLeaveStockBill = new()
                    {
                        OrderNumber = retailOrder.Number,
                        CustomerOrderNumber = retailOrder.CustomerOrderNumber,
                        CustomerCode = retailOrder.Customer!.Code,
                        CustomerName = retailOrder.Customer!.Name,
                        SalesLensCodeR = detailR.Contract_Lens!.Lens!.SalesLensCode,
                        FactoryLensCodeR = detailR.Contract_Lens!.Lens!.FactoryLensCode,
                        SPHR = detailR.SPH,
                        CYLR = detailR.CYL,
                        ADDR = detailR.ADD,
                        AxisR = detailR.Axis,
                        QtyR = detailR.Qty,
                        SalesLensCodeL = detailL.Contract_Lens!.Lens!.SalesLensCode,
                        FactoryLensCodeL = detailL.Contract_Lens!.Lens!.FactoryLensCode,
                        SPHL = detailL.SPH,
                        CYLL = detailL.CYL,
                        ADDL = detailL.ADD,
                        AxisL = detailL.Axis,
                        QtyL = detailL.Qty,
                        Remark = retailOrder.Remark
                    };
                    leaveStockBill.RetailOrderLeaveStockBills.Add(retailOrderLeaveStockBill);
                }
                if (order.BusinessOrderType == LeaveStockBusinessOrderTypeEnum.BulkOrder.ToString())
                {
                    var bulkOrder = await _db.BulkOrder
                .Include(x => x.Customer).Include(x => x.Contract)
                .Include(x => x.BulkOrderDetails).ThenInclude(x => x.BulkOrderDetail_LensDetails)
                .Include(x => x.BulkOrderDetails).ThenInclude(x => x.Warehouse)
                .Include(x => x.BulkOrderDetails).ThenInclude(x => x.Contract_Lens).ThenInclude(x => x!.Lens).AsNoTracking().FindByIdAsync(order.BusinessOrderId!.Value);
                    if (bulkOrder == null)
                        continue;

                    BulkOrderLeaveStockBill bulkOrderLeaveStockBill = new()
                    {
                        OrderNumber = order.Number,
                        CustomerOrderNumber = bulkOrder.CustomerOrderNumber,
                        CustomerCode = bulkOrder.Customer!.Code,
                        CustomerName = bulkOrder.Customer!.Name,
                        CreatedByName = bulkOrder.CreatedByName,
                        CreatedOn = order.CreatedOn,
                        Remark = order.Remark,
                    };
                    foreach (var orderDetail in order.LeaveStockOrderDetails)
                    {
                        var detail = new BulkOrderLeaveStockBillDetail()
                        {
                            WarehouseCode = orderDetail.Warehouse!.Code,
                            WarehouseName = orderDetail.Warehouse!.Name,
                            SalesLensCode = orderDetail.Lens!.SalesLensCode,
                            FactoryLensCode = orderDetail.Lens!.FactoryLensCode,
                        };
                        var sphs = orderDetail.LeaveStockOrderDetail_LensDetails.Select(s => s.SPH).Distinct().ToList();
                        foreach (var sph in sphs)
                        {
                            var ld = new BulkOrderLeaveStockBillDetail_LensDetail
                            {
                                SPH = sph
                            };
                            var lensDetails = orderDetail.LeaveStockOrderDetail_LensDetails.Where(x => x.SPH == sph).ToList();
                            foreach (var lensDetail in orderDetail.LeaveStockOrderDetail_LensDetails)
                            {
                                if (lensDetail.CYL == 0)
                                {
                                    ld.CELL0 = lensDetail.Qty;
                                }
                                if (lensDetail.CYL == -25)
                                {
                                    ld.CELL25 = lensDetail.Qty;
                                }
                                if (lensDetail.CYL == -50)
                                {
                                    ld.CELL50 = lensDetail.Qty;
                                }
                                if (lensDetail.CYL == -75)
                                {
                                    ld.CELL75 = lensDetail.Qty;
                                }
                                if (lensDetail.CYL == -100)
                                {
                                    ld.CELL100 = lensDetail.Qty;
                                }
                                if (lensDetail.CYL == -125)
                                {
                                    ld.CELL125 = lensDetail.Qty;
                                }
                                if (lensDetail.CYL == -150)
                                {
                                    ld.CELL150 = lensDetail.Qty;
                                }
                                if (lensDetail.CYL == -175)
                                {
                                    ld.CELL175 = lensDetail.Qty;
                                }
                                if (lensDetail.CYL == -200)
                                {
                                    ld.CELL200 = lensDetail.Qty;
                                }
                                if (lensDetail.CYL == -225)
                                {
                                    ld.CELL225 = lensDetail.Qty;
                                }
                                if (lensDetail.CYL == -250)
                                {
                                    ld.CELL250 = lensDetail.Qty;
                                }
                                if (lensDetail.CYL == -275)
                                {
                                    ld.CELL275 = lensDetail.Qty;
                                }
                                if (lensDetail.CYL == -300)
                                {
                                    ld.CELL300 = lensDetail.Qty;
                                }
                                if (lensDetail.CYL == -325)
                                {
                                    ld.CELL325 = lensDetail.Qty;
                                }
                                if (lensDetail.CYL == -350)
                                {
                                    ld.CELL350 = lensDetail.Qty;
                                }
                                if (lensDetail.CYL == -375)
                                {
                                    ld.CELL375 = lensDetail.Qty;
                                }
                                if (lensDetail.CYL == -400)
                                {
                                    ld.CELL400 = lensDetail.Qty;
                                }
                                if (lensDetail.CYL == -425)
                                {
                                    ld.CELL425 = lensDetail.Qty;
                                }
                                if (lensDetail.CYL == -450)
                                {
                                    ld.CELL450 = lensDetail.Qty;
                                }

                            }
                            detail.LensDetails.Add(ld);
                        }
                        bulkOrderLeaveStockBill.Details.Add(detail);
                    }
                    leaveStockBill.BulkOrderLeaveStockBills.Add(bulkOrderLeaveStockBill);
                }
            }
            return leaveStockBill;
        }
        /// <summary>
        /// 导出缺少出库
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<LensViewResponse> ExportLackLeaveStock(ExportLackLeaveStockRequest request)
        {
            if (request.BusinessOrderType == LeaveStockBusinessOrderTypeEnum.BulkOrder.ToString())
            {
                var detail = await _db.BulkOrderDetail.Include(x => x.BulkOrder).Include(x => x.BulkOrderDetail_LensDetails).Include(x => x.Warehouse).Include(x => x.Contract_Lens).ThenInclude(x => x!.Lens).FindByIdAsync(request.Id);
                if (detail == null)
                    throw new ApiException("批量订单不存在!");
                foreach (var item in detail.BulkOrderDetail_LensDetails)
                {
                    item.Qty -= item.LeaveStockQty;
                    if (item.Qty <= 0)
                        item.Qty = 0;
                }
                return _mapper.Map<LensViewResponse>(detail);
            }
            else
            {
                return new LensViewResponse();
            }
        }
        /// <summary>
        /// 获取XY表汇总
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<List<LensViewResponse>> GetLensDetailSummary(ExportLensDetailSummaryRequest request)
        {
            var query = _db.LeaveStockOrder.AsNoTracking().Where(x => x.CreatedOn >= request.CreatedOnStart.ToStart() && x.CreatedOn <= request.CreatedOnEnd.ToEnd() && x.Status == LeaveStockOrderStatusEnum.Checked.ToString() && (x.BusinessOrderType == LeaveStockBusinessOrderTypeEnum.RetailOrder.ToString().ToString() || x.BusinessOrderType == LeaveStockBusinessOrderTypeEnum.BulkOrder.ToString()));

            var list = await (from a in query
                              join b in _db.LeaveStockOrderDetail.Where(x => request.LensId == null || x.LensId == request.LensId) on a.Id equals b.LeaveStockOrderId
                              join c in _db.LeaveStockOrderDetail_LensDetail.Where(x => x.Qty > 0) on b.Id equals c.LeaveStockOrderDetailId
                              join e in _db.Lens on b.LensId equals e.Id
                              from f in _db.RetailOrder.Where(x => x.CustomerId == request.CustomerId).DefaultIfEmpty()
                              from g in _db.BulkOrder.Where(x => x.CustomerId == request.CustomerId).DefaultIfEmpty()
                              where a.BusinessOrderId == f.Id || a.BusinessOrderId == g.Id
                              group new { a, b, c } by new { b.LensId, c.DegreesType, c.SPH, c.CYL } into g
                              select new
                              {
                                  Lens = g.Where(x => x.b.LensId == g.Key.LensId).Select(s => s.b.Lens).FirstOrDefault(),
                                  g.Key.DegreesType,
                                  g.Key.SPH,
                                  g.Key.CYL,
                                  Qty = g.Sum(s => s.c.Qty)
                              }
               ).ToListAsync();

            if (list.Count <= 0)
            {
                throw new ApiException("XY表汇总为空!");
            }

            List<LensViewResponse> lensViews = new List<LensViewResponse>();
            var lensIds = list.Select(s => s.Lens.Id).Distinct().ToList();
            foreach (var lensId in lensIds)
            {
                var details = list.Where(x => x.Lens.Id == lensId).ToList();
                if (details.Count > 0)
                {
                    var lensView = new LensViewResponse()
                    {
                        Lens = _mapper.Map<LensResponse>(details[0].Lens)
                    };
                    foreach (var detail in details)
                    {
                        LensDetailResponse lensDetail = new()
                        {
                            DegreesType = detail.DegreesType,
                            SPH = detail.SPH,
                            CYL = detail.CYL,
                            Qty = detail.Qty,
                        };
                        lensView.LensDetails.Add(lensDetail);
                    }
                    lensViews.Add(lensView);
                }
            }
            return lensViews;
        }
        /// <summary>
        /// 扫描条码出库
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        /// <exception cref="ApiException"></exception>
        public async Task ScanBarCodeLeaveStock(ScanBarCodeLeaveStockRequest request)
        {
            string sph = "";
            string cyl = "";
            string lensCode = "";
            string degreeType = "-";
            if (!request.BarCode.Contains('-'))
                throw new ApiException("条码格式错误,请检查!");
            if (request.BarCode.Contains('+'))
            {
                string[] strs = request.BarCode.Replace("+", "-").Split('-');
                lensCode = strs[0].Trim();
                sph = "+" + strs[1];
                cyl = strs[2];
                degreeType = "+";
            }
            else
            {
                string[] strs = request.BarCode.Split('-');
                lensCode = strs[0].Trim();
                sph = "-" + strs[1];
                cyl = strs[2];
            }
            var lens = await _db.Lens.Where(x => x.SalesLensCode == lensCode || x.SalesLensCode == lensCode + degreeType).FirstOrDefaultAsync();
            if (lens == null)
                throw new ApiException($"镜种{lensCode}不存在,请检查!");
            var order = new LeaveStockOrderSaveRequest()
            {
                BusinessType = request.BusinessType
            };
            LeaveStockOrderDetailSaveRequest detail = new()
            {
                WarehouseId = request.WarehouseId,
                LensId = lens.Id
            };
            string degreesType = "-/-";
            if (sph.ToInt() > 0)
                degreesType = "+/-";
            LensDetailResponse lensDetail = new()
            {
                DegreesType = degreesType,
                SPH = sph.ToInt(),
                CYL = cyl.ToInt(),
                Qty = request.Qty
            };
            detail.LensDetails.Add(lensDetail);
            order.LeaveStockOrderDetails.Add(detail);
            await Save(order, true);
        }
        private IQueryable<LeaveStockOrder> Where(PageRequest<LeaveStockOrderRequest> request)
        {
            IQueryable<LeaveStockOrder> query = _db.LeaveStockOrder
                .Include(x => x.LeaveStockOrderDetails).ThenInclude(x => x.LeaveStockOrderDetail_LensDetails)
                .Include(x => x.LeaveStockOrderDetails).ThenInclude(x => x.Warehouse)
                .Include(x => x.LeaveStockOrderDetails).ThenInclude(x => x.Lens).AsNoTracking();

            if (!request.Query.Number.IsNullOrWhiteSpace())
            {
                query = query.Where(x => x.Number.Contains(request.Query.Number!));
            }
            if (!request.Query.BusinessOrderNumber.IsNullOrWhiteSpace())
            {
                query = query.Where(x => x.BusinessOrderNumber!.Contains(request.Query.BusinessOrderNumber!));
            }
            if (!request.Query.BusinessOrderType.IsNullOrWhiteSpace())
            {
                query = query.Where(x => x.BusinessOrderType == request.Query.BusinessOrderType);
            }
            if (!request.Query.BusinessType.IsNullOrWhiteSpace())
            {
                query = query.Where(x => x.BusinessType == request.Query.BusinessType);
            }
            if (!request.Query.LeaveStockWay.IsNullOrWhiteSpace())
            {
                query = query.Where(x => x.LeaveStockWay!.Contains(request.Query.LeaveStockWay!));
            }
            if (!request.Query.CreatedByName.IsNullOrWhiteSpace())
            {
                query = query.Where(x => x.CreatedByName.Contains(request.Query.CreatedByName!));
            }
            if (request.Query.CreatedOnStart != null)
            {
                query = query.Where(x => x.CreatedOn >= request.Query.CreatedOnStart.Value.ToStart());
            }
            if (request.Query.CreatedOnEnd != null)
            {
                query = query.Where(x => x.CreatedOn <= request.Query.CreatedOnEnd.Value.ToEnd());
            }
            if (!request.Query.Status.IsNullOrWhiteSpace())
            {
                query = query.Where(x => x.Status == request.Query.Status);
            }
            if (request.Query.WarehouseId != null)
            {
                query = query.Where(x => x.LeaveStockOrderDetails.Select(s => s.WarehouseId).Contains(request.Query.WarehouseId.Value));
            }
            if (request.Query.LensId != null)
            {
                query = query.Where(x => x.LeaveStockOrderDetails.Select(s => s.LensId).Contains(request.Query.LensId.Value));
            }
            //if (request.Query.Status == LeaveStockOrderStatusEnum.Pending.ToString())
            //{
            //    query = query.OrderByDescending(x => x.CreatedOn);
            //}
            //else if (request.Query.Status == LeaveStockOrderStatusEnum.Checked.ToString())
            //{
            //    query = query.OrderByDescending(x => x.CheckedOn);
            //}
            //else
            //{
            //    query = query.OrderByDescending(x => x.UpdatedOn);
            //}
            query = query.OrderByDescending(x => x.CreatedOn);
            return query;
        }
        private async Task Check(LeaveStockOrder order)
        {
            foreach (var lsod in order.LeaveStockOrderDetails)
            {
                if (lsod.LeaveStockOrderDetail_LensDetails.Sum(s => s.Qty) <= 0)
                    continue;
                var stock = await _db.Stock.GetByWarehouseLens(lsod.WarehouseId, lsod.LensId);
                StockActionLog stockActionLog = new()
                {
                    StockActionType = StockActionTypeEnum.LeaveStock.ToString(),
                    BusinessOrderId = order.Id,
                    BusinessOrderNumber = order.Number,
                    BusinessOrderDetailId = lsod.Id,
                    BusinessType = order.BusinessType,
                    WarehouseId = lsod.WarehouseId,
                    LensId = lsod.LensId,
                };
                foreach (var lsod_ld in lsod.LeaveStockOrderDetail_LensDetails)
                {
                    var stockDetail = stock.GetByRange(lsod_ld.DegreesType, lsod_ld.SPH, lsod_ld.CYL);
                    int stockQty = stockDetail.Qty;
                    stockDetail.Qty -= lsod_ld.Qty;
                    if (stockDetail.Qty < 0)
                    {
                        throw new ApiException($"出库单号{order.Number}的仓库{lsod.Warehouse?.Code}镜种{lsod.Lens?.SalesLensCode}度数SPH:{lsod_ld.SPH},CYL{lsod_ld.CYL}库存片数不足扣库");
                    }
                    StockActionLogDetail stockActionLogDetail = new()
                    {
                        DegreesType = lsod_ld.DegreesType,
                        SPH = lsod_ld.SPH,
                        CYL = lsod_ld.CYL,
                        ADD = lsod_ld.ADD,
                        Qty = lsod_ld.Qty,
                        StockQty = stockQty
                    };
                    stockActionLog.StockActionLogDetails.Add(stockActionLogDetail);
                }
                await _db.AddAsync(stockActionLog);
            }
            if (order.BusinessOrderType == LeaveStockBusinessOrderTypeEnum.RetailOrder.ToString())
            {
                var ro = await _db.RetailOrder.Include(x => x.RetailOrderDetails).FindByIdAsync(order.BusinessOrderId!.Value);
                if (ro == null)
                    throw new ApiException($"出库单号{order.Number}对应散镜订单号{order.BusinessOrderNumber}不存在!");

                ro.Status = RetailOrderStatusEnum.Delivered.ToString();
            }
            else if (order.BusinessOrderType == LeaveStockBusinessOrderTypeEnum.BulkOrder.ToString())
            {
                var bo = await _db.BulkOrder.Include(x => x.BulkOrderDetails).ThenInclude(x => x.BulkOrderDetail_LensDetails).FindByIdAsync(order.BusinessOrderId!.Value);
                if (bo == null)
                    throw new ApiException($"出库单号{order.Number}对应批量订单号{order.BusinessOrderNumber}不存在!");

                foreach (var lsod in order.LeaveStockOrderDetails)
                {
                    var bod = bo.BulkOrderDetails.Where(x => x.Id == lsod.BusinessOrderDetailId && x.BulkOrderDetail_LensDetails.Sum(s => s.Qty) > 0).FirstOrDefault();
                    if (bod != null)
                    {
                        foreach (var lsod_ld in lsod.LeaveStockOrderDetail_LensDetails)
                        {
                            var bod_ld = bod.BulkOrderDetail_LensDetails.Where(x => x.DegreesType == lsod_ld.DegreesType && x.SPH == lsod_ld.SPH && x.CYL == lsod_ld.CYL).FirstOrDefault();
                            if (bod_ld != null)
                            {
                                bod_ld.LeaveStockQty += lsod_ld.Qty;
                                if (bod_ld.LeaveStockQty > bod_ld.Qty)
                                {
                                    throw new ApiException($"出库单号{order.Number}对应批量订单号{order.BusinessOrderNumber}仓库{lsod.Warehouse?.Code}的镜种{lsod.Lens?.SalesLensCode}度数SPH:{lsod_ld.SPH},CYL{lsod_ld.CYL}不能超出下单片数,请检查");
                                }
                            }
                            else
                                throw new ApiException($"出库单号{order.Number}仓库{lsod.Warehouse?.Code}的镜种{lsod.Lens?.SalesLensCode}度数SPH:{lsod_ld.SPH},CYL{lsod_ld.CYL}超出对应批量订单号{order.BusinessOrderNumber}下单度数库存范围!");
                        }
                    }
                    var qty = bo.BulkOrderDetails.SelectMany(s => s.BulkOrderDetail_LensDetails).Sum(s => s.Qty - s.LeaveStockQty);

                    if (qty > 0)
                    {
                        bo.Status = BulkOrderStatusEnum.PartialDelivered.ToString();
                    }
                    else if (qty == 0)
                    {
                        bo.Status = BulkOrderStatusEnum.AllDelivered.ToString();
                    }
                    else
                    {
                        throw new ApiException($"出库单号{order.Number}对应批量订单号{order.BusinessOrderNumber}不能超出下单片数,请检查!");
                    }
                }
            }
            else if (order.BusinessOrderType == LeaveStockBusinessOrderTypeEnum.TransferOrder.ToString())
            {
                var tfo = await _db.TransferOrder.Include(x => x.TransferOrderDetails).ThenInclude(x => x.TransferOrderDetail_LensDetails).FindByIdAsync(order.BusinessOrderId!.Value);
                if (tfo == null)
                    throw new ApiException($"出库单号{order.Number}对应调拨单号{order.BusinessOrderNumber}不存在!");

                var enterOrder = new EnterStockOrder()
                {
                    Number = await _serialNumberSvc.GetSerialNumber(SerialNumberTypeEnum.EnterStockOrder),
                    LeaveStockOrderId = order.Id,
                    BusinessOrderId = tfo.Id,
                    BusinessOrderNumber = tfo.Number,
                    BusinessOrderType = EnterStockBusinessOrderTypeEnum.TransferOrder.ToString(),
                    BusinessType = EnterStockBusinessTypeEnum.TransferEnterStock.ToString(),
                    Status = EnterStockOrderStatusEnum.Pending.ToString(),
                    Remark = order.Remark,
                };

                foreach (var lsod in order.LeaveStockOrderDetails)
                {
                    var tfod = tfo.TransferOrderDetails.Where(x => x.Id == lsod.BusinessOrderDetailId && x.TransferOrderDetail_LensDetails.Sum(s => s.Qty) > 0).FirstOrDefault();

                    if (tfod != null)
                    {
                        var enterOrderDetail = new EnterStockOrderDetail()
                        {
                            WarehouseId = tfod.InWarehouseId,
                            LensId = tfod.LensId,
                            BusinessOrderDetailId = tfod.Id
                        };
                        foreach (var lsod_ld in lsod.LeaveStockOrderDetail_LensDetails)
                        {
                            var tfod_ld = tfod.TransferOrderDetail_LensDetails.Where(x => x.DegreesType == lsod_ld.DegreesType && x.SPH == lsod_ld.SPH && x.CYL == lsod_ld.CYL).FirstOrDefault();
                            if (tfod_ld != null)
                            {
                                tfod_ld.LeaveStockQty += lsod_ld.Qty;
                                if (tfod_ld.LeaveStockQty > tfod_ld.Qty)
                                {
                                    throw new ApiException($"出库单号{order.Number}对应调拨单号{order.BusinessOrderNumber}仓库{lsod.Warehouse?.Code}的镜种{lsod.Lens?.SalesLensCode}度数SPH:{lsod_ld.SPH},CYL{lsod_ld.CYL}不能超出下单片数,请检查");
                                }
                                var enterOrderDetail_LensDetail = new EnterStockOrderDetail_LensDetail()
                                {
                                    DegreesType = lsod_ld.DegreesType,
                                    SPH = lsod_ld.SPH,
                                    CYL = lsod_ld.CYL,
                                    ADD = lsod_ld.ADD,
                                    Qty = lsod_ld.Qty
                                };
                                enterOrderDetail.EnterStockOrderDetail_LensDetails.Add(enterOrderDetail_LensDetail);
                            }
                            else
                                throw new ApiException($"出库单号{order.Number}仓库{lsod.Warehouse?.Code}的镜种{lsod.Lens?.SalesLensCode}度数SPH:{lsod_ld.SPH},CYL{lsod_ld.CYL}超出对应调拨单号{order.BusinessOrderNumber}下单度数库存范围!");
                        }
                        var qty = tfo.TransferOrderDetails.SelectMany(s => s.TransferOrderDetail_LensDetails).Sum(s => s.Qty - s.LeaveStockQty);
                        if (qty < 0)
                        {
                            throw new ApiException($"出库单号{order.Number}对应调拨单号{order.BusinessOrderNumber}不能超出下单片数,请检查!");
                        }
                        //if (qty > 0)
                        //{
                        //    tfo.Status = TransferOrderStatusEnum.PartialReceived.ToString();
                        //}
                        //else if (qty == 0)
                        //{
                        //    tfo.Status = TransferOrderStatusEnum.AllReceived.ToString();
                        //}
                        //else
                        //{
                        //    throw new ApiException("调拨单不能超出收货片数,请检查!");
                        //}
                        enterOrder.EnterStockOrderDetails.Add(enterOrderDetail);
                    }
                    
                }
                await _db.AddAsync(enterOrder);
            }
            else if (order.BusinessOrderType == LeaveStockBusinessOrderTypeEnum.TransferLensOrder.ToString())
            {
                var tflo = await _db.TransferLensOrder.Include(x => x.TransferLensOrderDetails).ThenInclude(x => x.TransferLensOrderDetail_LensDetails).FindByIdAsync(order.BusinessOrderId!.Value);
                if (tflo == null)
                    throw new ApiException($"出库单号{order.Number}对应镜种转换单号{order.BusinessOrderNumber}不存在!");

                var enterOrder = new EnterStockOrder()
                {
                    Number = await _serialNumberSvc.GetSerialNumber(SerialNumberTypeEnum.EnterStockOrder),
                    LeaveStockOrderId = order.Id,
                    BusinessOrderId = tflo.Id,
                    BusinessOrderNumber = tflo.Number,
                    BusinessOrderType = EnterStockBusinessOrderTypeEnum.TransferLensOrder.ToString(),
                    BusinessType = EnterStockBusinessTypeEnum.TransferEnterStock.ToString(),
                    Status = EnterStockOrderStatusEnum.Pending.ToString(),
                    Remark = order.Remark,
                };

                foreach (var lsod in order.LeaveStockOrderDetails)
                {
                    var tflod = tflo.TransferLensOrderDetails.Where(x => x.Id == lsod.BusinessOrderDetailId && x.TransferLensOrderDetail_LensDetails.Sum(s => s.Qty) > 0).FirstOrDefault();

                    if (tflod != null)
                    {
                        var enterOrderDetail = new EnterStockOrderDetail()
                        {
                            WarehouseId = tflod.InWarehouseId,
                            LensId = tflod.InLensId,
                            BusinessOrderDetailId = tflod.Id
                        };
                        foreach (var lsod_ld in lsod.LeaveStockOrderDetail_LensDetails)
                        {
                            var tflod_ld = tflod.TransferLensOrderDetail_LensDetails.Where(x => x.DegreesType == lsod_ld.DegreesType && x.SPH == lsod_ld.SPH && x.CYL == lsod_ld.CYL).FirstOrDefault();
                            if (tflod_ld != null)
                            {
                                tflod_ld.LeaveStockQty += lsod_ld.Qty;
                                if (tflod_ld.LeaveStockQty > tflod_ld.Qty)
                                {
                                    throw new ApiException($"出库单号{order.Number}对应的镜种转换单号{order.BusinessOrderNumber}仓库{lsod.Warehouse?.Code}的镜种{lsod.Lens?.SalesLensCode}度数SPH:{lsod_ld.SPH},CYL{lsod_ld.CYL}不能超出下单片数,请检查!");
                                }
                                var enterOrderDetail_LensDetail = new EnterStockOrderDetail_LensDetail()
                                {
                                    DegreesType = lsod_ld.DegreesType,
                                    SPH = lsod_ld.SPH,
                                    CYL = lsod_ld.CYL,
                                    ADD = lsod_ld.ADD,
                                    Qty = lsod_ld.Qty
                                };
                                enterOrderDetail.EnterStockOrderDetail_LensDetails.Add(enterOrderDetail_LensDetail);
                            }
                            else
                                throw new ApiException($"出库单号{order.Number}仓库{lsod.Warehouse?.Code}的镜种{lsod.Lens?.SalesLensCode}度数SPH:{lsod_ld.SPH},CYL{lsod_ld.CYL}超出对应镜种转换单号{order.BusinessOrderNumber}下单度数库存范围!");
                        }
                        enterOrder.EnterStockOrderDetails.Add(enterOrderDetail);
                    }
                    
                }
                var qty = tflo.TransferLensOrderDetails.SelectMany(s => s.TransferLensOrderDetail_LensDetails).Sum(s => s.Qty - s.LeaveStockQty);

                if (qty < 0)
                {
                    throw new ApiException($"出库单号{order.Number}对应镜种转换单号{order.BusinessOrderNumber}不能超出下单片数,请检查!");
                }
                //if (qty > 0)
                //{
                //    tfo.Status = TransferOrderStatusEnum.PartialReceived.ToString();
                //}
                //else if (qty == 0)
                //{
                //    tfo.Status = TransferOrderStatusEnum.AllReceived.ToString();
                //}
                //else
                //{
                //    throw new ApiException("调拨单不能超出收货片数,请检查!");
                //}
                await _db.AddAsync(enterOrder);
            }
            else if (order.BusinessOrderType == LeaveStockBusinessOrderTypeEnum.InventoryOrder.ToString())
            {
                var io = await _db.InventoryOrder.FindByIdAsync(order.BusinessOrderId!.Value);
                if (io == null)
                    throw new ApiException($"出库单号{order.Number}对应库存盘点单号{order.BusinessOrderNumber}不存在!");
                var eso = await _db.EnterStockOrder.Where(x => x.BusinessOrderId == io.Id && x.BusinessOrderType == LeaveStockBusinessOrderTypeEnum.InventoryOrder.ToString() && x.Status == LeaveStockOrderStatusEnum.Canceled.ToString()).FirstOrDefaultAsync();
                if (eso == null || eso.Status == LeaveStockOrderStatusEnum.Checked.ToString())
                {
                    io.Status = InventoryOrderStatusEnum.Finished.ToString();
                    io.FinishedBy = _currentUser.Id;
                    io.FinishedByName = _currentUser.Name;
                    io.FinishedOn = DateTime.Now;
                }
            }
            order.Status = LeaveStockOrderStatusEnum.Checked.ToString();
            order.CheckedBy = _currentUser.Id;
            order.CheckedByName = _currentUser.Name;
            order.CheckedOn = DateTime.Now;
        }
        private async Task UnCheckOrCancel(LeaveStockOrder order)
        {
            if (order.Status == LeaveStockOrderStatusEnum.Checked.ToString())
            {
                var stockActionLogs = await _db.StockActionLog.Where(x => x.BusinessOrderId == order.Id && x.StockActionType == StockActionTypeEnum.LeaveStock.ToString()).ToListAsync();
                if (stockActionLogs != null)
                {
                    stockActionLogs.ForEach(x => x.IsEnable = false);
                }
                foreach (var lsod in order.LeaveStockOrderDetails)
                {
                    var stock = await _db.Stock.GetByWarehouseLens(lsod.WarehouseId,lsod.LensId);
                    foreach (var lsod_ld in lsod.LeaveStockOrderDetail_LensDetails)
                    {
                        //修改库存片数
                        var stockDetail = stock.GetByRange(lsod_ld.DegreesType,lsod_ld.SPH,lsod_ld.CYL);
                        stockDetail.Qty += lsod_ld.Qty;
                    }
                }
                if (order.BusinessOrderType == LeaveStockBusinessOrderTypeEnum.RetailOrder.ToString())
                {
                    var ro = await _db.RetailOrder.Include(x => x.RetailOrderDetails).FindByIdAsync(order.BusinessOrderId!.Value);
                    if (ro == null)
                        throw new ApiException($"出库单号{order.Number}对应散镜订单号{order.BusinessOrderNumber}不存在!");

                    if(ro.Status == RetailOrderStatusEnum.Finished.ToString())
                        throw new ApiException($"出库单号{order.Number}对应散镜订单号{order.BusinessOrderNumber}已完成,不能弃审或取消出库单!");

                    ro.Status = RetailOrderStatusEnum.Delivered.ToString();
                }
                if (order.BusinessOrderType == LeaveStockBusinessOrderTypeEnum.BulkOrder.ToString())
                {
                    var bo = await _db.BulkOrder.Include(x => x.BulkOrderDetails).ThenInclude(x => x.BulkOrderDetail_LensDetails).FindByIdAsync(order.BusinessOrderId!.Value);
                    if (bo == null)
                        throw new ApiException($"出库单号{order.Number}对应批量订单号{order.BusinessOrderNumber}不存在!");

                    if (bo.Status == BulkOrderStatusEnum.Finished.ToString())
                        throw new ApiException($"出库单号{order.Number}对应批量订单号{order.BusinessOrderNumber}已完成,不能弃审或取消出库单!");

                    foreach (var lsod in order.LeaveStockOrderDetails)
                    {
                        var bod = bo.BulkOrderDetails.Where(x => x.Id == lsod.BusinessOrderDetailId && x.BulkOrderDetail_LensDetails.Sum(s => s.Qty) > 0).FirstOrDefault();
                        if (bod != null)
                        {
                            foreach (var lsod_ld in lsod.LeaveStockOrderDetail_LensDetails)
                            {
                                var bod_ld = bod.BulkOrderDetail_LensDetails.Where(x => x.DegreesType == lsod_ld.DegreesType && x.SPH == lsod_ld.SPH && x.CYL == lsod_ld.CYL).FirstOrDefault();
                                if (bod_ld != null)
                                {
                                    bod_ld.LeaveStockQty -= lsod_ld.Qty;
                                }
                            }
                        }
                        var qty = bo.BulkOrderDetails.SelectMany(s => s.BulkOrderDetail_LensDetails).Sum(s => s.Qty - s.LeaveStockQty);
                        var totalQty = bo.BulkOrderDetails.SelectMany(s => s.BulkOrderDetail_LensDetails).Sum(s => s.Qty);
                        if (qty - totalQty == 0)
                        {
                            bo.Status = BulkOrderStatusEnum.Delivery.ToString();
                        }
                        else if (qty > 0)
                        {
                            bo.Status = BulkOrderStatusEnum.PartialDelivered.ToString();
                        }
                        else if (qty == 0)
                        {
                            bo.Status = BulkOrderStatusEnum.AllDelivered.ToString();
                        }
                    }
                }
                else if (order.BusinessOrderType == LeaveStockBusinessOrderTypeEnum.TransferOrder.ToString())
                {
                    var tfo = await _db.TransferOrder.Include(x => x.TransferOrderDetails).ThenInclude(x => x.TransferOrderDetail_LensDetails).FindByIdAsync(order.BusinessOrderId!.Value);
                    if (tfo == null)
                        throw new ApiException($"出库单号{order.Number}对应调拨单号{order.BusinessOrderNumber}不存在!");

                    foreach (var lsod in order.LeaveStockOrderDetails)
                    {
                        var tfod = tfo.TransferOrderDetails.Where(x => x.Id == lsod.BusinessOrderDetailId && x.TransferOrderDetail_LensDetails.Sum(s => s.Qty) > 0).FirstOrDefault();

                        if (tfod != null)
                        {
                            foreach (var lsod_ld in lsod.LeaveStockOrderDetail_LensDetails)
                            {
                                var tfod_ld = tfod.TransferOrderDetail_LensDetails.Where(x => x.DegreesType == lsod_ld.DegreesType && x.SPH == lsod_ld.SPH && x.CYL == lsod_ld.CYL).FirstOrDefault();
                                if (tfod_ld != null)
                                {
                                    tfod_ld.LeaveStockQty -= lsod_ld.Qty;
                                }
                            }
                        }
                    }
                }
                else if (order.BusinessOrderType == LeaveStockBusinessOrderTypeEnum.TransferLensOrder.ToString())
                {
                    var tflo = await _db.TransferLensOrder.Include(x => x.TransferLensOrderDetails).ThenInclude(x => x.TransferLensOrderDetail_LensDetails).FindByIdAsync(order.BusinessOrderId!.Value);
                    if (tflo == null)
                        throw new ApiException($"出库单号{order.Number}对应镜种转换单号{order.BusinessOrderNumber}不存在!");

                    foreach (var lsod in order.LeaveStockOrderDetails)
                    {
                        var tflod = tflo.TransferLensOrderDetails.Where(x => x.Id == lsod.BusinessOrderDetailId && x.TransferLensOrderDetail_LensDetails.Sum(s => s.Qty) > 0).FirstOrDefault();

                        if (tflod != null)
                        {
                            foreach (var lsod_ld in lsod.LeaveStockOrderDetail_LensDetails)
                            {
                                var tfold_ld = tflod.TransferLensOrderDetail_LensDetails.Where(x => x.DegreesType == lsod_ld.DegreesType && x.SPH == lsod_ld.SPH && x.CYL == lsod_ld.CYL).FirstOrDefault();
                                if (tfold_ld != null)
                                {
                                    tfold_ld.LeaveStockQty -= lsod_ld.Qty;
                                }
                            }
                        }
                    }
                }
                else if (order.BusinessOrderType == LeaveStockBusinessOrderTypeEnum.InventoryOrder.ToString())
                {
                    var io = await _db.InventoryOrder.FindByIdAsync(order.BusinessOrderId!.Value);
                    if (io == null)
                        throw new ApiException($"出库单号{order.Number}对应库存盘点单号{order.BusinessOrderNumber}不存在!");
                    if (io.Status == InventoryOrderStatusEnum.Finished.ToString())
                        throw new ApiException($"出库单号{order.Number}对应库存盘点单号{order.BusinessOrderNumber}已完成,不能弃审或取消!");
                }
            }
        }
        private async Task ModifyBusinessOrder(LeaveStockOrder order)
        {
            if (order.BusinessOrderType == LeaveStockBusinessOrderTypeEnum.RetailOrder.ToString())
            {
                //取出此业务单已创建未取消的出库单总片数
                var leaveStockQty = await _db.LeaveStockOrder.GetLeaveStockQtyAsync(order.BusinessOrderType, order.BusinessOrderId!.Value, order.Id);
                if (leaveStockQty > 0)
                {
                    throw new ApiException("散镜订单不能超出发货片数,请检查!");
                }
            }
            if (order.BusinessOrderType == LeaveStockBusinessOrderTypeEnum.BulkOrder.ToString())
            {
                //取出此业务单已创建未取消的出库单总片数
                var leaveStockQty = await _db.LeaveStockOrder.GetLeaveStockQtyAsync(order.BusinessOrderType, order.BusinessOrderId!.Value, order.Id);
                var bo = await _db.BulkOrder.Include(x => x.BulkOrderDetails).ThenInclude(x => x.BulkOrderDetail_LensDetails).FindByIdAsync(order.BusinessOrderId!.Value);
                if (bo == null)
                    throw new ApiException("批量订单不存在!");

                var qty = bo.BulkOrderDetails.SelectMany(s => s.BulkOrderDetail_LensDetails).Sum(s => s.Qty);
                if (qty - leaveStockQty < 0)
                {
                    throw new ApiException("批量订单不能超出发货片数,请检查!");
                }
            }
            else if (order.BusinessOrderType == LeaveStockBusinessOrderTypeEnum.TransferOrder.ToString())
            {
                //取出此业务单已创建未取消的出库单总片数
                var leaveStockQty = await _db.LeaveStockOrder.GetLeaveStockQtyAsync(order.BusinessOrderType, order.BusinessOrderId!.Value, order.Id);
                var to = await _db.TransferOrder.Include(x => x.TransferOrderDetails).ThenInclude(x => x.TransferOrderDetail_LensDetails).FindByIdAsync(order.BusinessOrderId!.Value);
                if (to == null)
                    throw new ApiException("调拨单不存在!");

                var qty = to.TransferOrderDetails.SelectMany(s => s.TransferOrderDetail_LensDetails).Sum(s => s.Qty);
                if (qty - leaveStockQty < 0)
                {
                    throw new ApiException("调拨单不能超出出库片数,请检查!");
                }
            }
            else if (order.BusinessOrderType == LeaveStockBusinessOrderTypeEnum.TransferLensOrder.ToString())
            {
                //取出此业务单已创建未取消的出库单总片数
                var leaveStockQty = await _db.LeaveStockOrder.GetLeaveStockQtyAsync(order.BusinessOrderType, order.BusinessOrderId!.Value, order.Id);
                var tflo = await _db.TransferLensOrder.Include(x => x.TransferLensOrderDetails).ThenInclude(x => x.TransferLensOrderDetail_LensDetails).FindByIdAsync(order.BusinessOrderId!.Value);
                if (tflo == null)
                    throw new ApiException("镜种转换单不存在!");

                var qty = tflo.TransferLensOrderDetails.SelectMany(s => s.TransferLensOrderDetail_LensDetails).Sum(s => s.Qty);
                if (leaveStockQty > 0)
                {
                    throw new ApiException("镜种转换单不能超出出库片数,请检查!");
                }
            }
        }
    }
}
